package com.ihisomp.util;

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

/**
 * 标题: ComUtil.java
 * 业务描述: 公用类
 * 作者: zy
 * 日期: 2021/9/10
 * 版本: V1.0
 */
public class ComUtil {

    /**
     * 加密密钥
     */
    public final static String ENCRYPT_KEY = "b80d025e865ececdcca0ad82931ec78e";

    /**
     * 获取32位UUID
     *
     * @return
     */
    public static String createUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 获取16位数据库主键
     *
     * @return
     */
    public static String createPrimaryKey() {
        return SequenceUtil.nextId();
    }

    /**
     * 获取系统时间
     *
     * @return 系统时间(yyyyMMddHHmmss)
     */
    public static String getDateTimeString() {
        return getDateTimeString(null);
    }

    /**
     * 日期转字符串(传null返回系统时间)
     *
     * @param date
     * @return yyyyMMddHHmmss
     */
    public static String getDateTimeString(Date date) {
        if (date == null) {
            date = new Date();
        }
        // 可以方便地修改日期格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String sysDate = dateFormat.format(date);
        return sysDate;
    }

    /**
     * 获取系统时间
     *
     * @return
     */
    public static Date getDateTime() {
        return new Date();
    }

    /**
     * 字符串转日期(传null返回系统时间)
     *
     * @param dateStr 格式正确时返回日期，否则返回null
     * @return
     */
    public static Date getDateTime(String dateStr) {
        if (dateStr == null || "".equals(dateStr.trim())) {
            return new Date();
        } else {
            dateStr = dateStr.replaceAll("[^0-9]", "");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = null;
            try {
                date = sdf.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            return day2 - day1;
        }
    }

    /**
     * 获取IP
     *
     * @return IP
     */
    public static String getIp() {
        String ip = "";
        try {
            HttpServletRequest request = getRequest();
            ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0
                    || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ip;
    }

    /**
     * 获取request对象
     *
     * @return request
     */
    public static HttpServletRequest getRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        return request;
    }

    /**
     * 对字符串进行加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);
        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密钥初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
        return cipher.doFinal(data);
    }

    /**
     * 对字符串进行解密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
        // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey securekey = keyFactory.generateSecret(dks);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密钥初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
        return cipher.doFinal(data);
    }

    /**
     * 加密算法
     *
     * @param field
     * @return
     */
    public static String encryptDbField(String field) {
        if (field == null) {
            return null;
        }
        try {
            byte[] bt = encrypt(field.getBytes(), ENCRYPT_KEY.getBytes());
            return new String(Base64.encodeBase64(bt));
        } catch (Exception e) {
            // 失败沿用原值
            return field;
        }
    }

    /**
     * 解密算法
     *
     * @param field
     * @return
     */
    public static String decryptDbField(String field) {
        if (field == null) {
            return null;
        }
        try {
            byte[] buf = new Base64().decode(field.getBytes());
            byte[] bt = decrypt(buf, ENCRYPT_KEY.getBytes());
            // 解密失败返回空值时返回原值
            String btStr = new String(bt);
            return field.equals("uJ2/yERKTfE=") || btStr.length() > 0 ? btStr : field;
        } catch (Exception e) {
            // 失败沿用原值
            return field;
        }
    }

    /**
     * 测试方法
     *
     * @param args
     */
    public static void main(String[] args) {
        String code = "1323131";
        String encode = encryptDbField(code);
        System.out.println(encode);
        String decode = decryptDbField(encode);
        System.out.println(decode);
    }
}
